/**
 * @Description: 这里的api模仿 vuex-pathify, 考虑到vuex-pathify暂时还未有3.x版本，自己写了一套兼容3.x的
 * @Author BPF
 * @create 2021/8/20 10:43
 */
import { computed } from 'vue'

const vuexHelper = {
  store: null,
  plugins: function () {
    return store => {
      // console.log('vuexHelper-helper.js', store, this)
      this.store = store
    }
  }
}

/**
 * 动态获取/更改vuex里面的state值
 * @param {string} path
 * @returns {WritableComputedRef<*>}
 * @example
 *  import {sync} from '~vuex-helper'   // 引入
 *  const userInfo_ = sync('user/info')  // 其中的 user是模块前缀名，info是模块里面state属性字段名， 这个数据结构是vue中的ref响应式的
 *  userInfo_.value  // 获取值 ，注意在vue3.0中的template中，直接放入userInfo即（{{userInfo}}），不需要加上userInfo.value 即({{userInfo.value}}),
 *                  // vue 3.x 响应式自动会捕捉的
 *  userInfo_.value = {}  // 设置值
 */
const sync = function (path = '') {
  const { store } = vuexHelper
  if (!path) {
    throw new Error('传入的路径path 不能为空')
  }
  return computed({
    get: () => {
      return path.split('/').reduce((pre, cur) => {
        return pre[cur]
      }, store.state)
    },
    set: val => {
      store.commit(path, val)
    }
  })
}

/**
 * 动态获取vuex里面的state值（不可修改）
 * @param path
 * @returns {WritableComputedRef<string>}
 * @example
 *  import {get} from '~vuex-helper'   // 引入
 *  const userInfo_ = get('user/info')  // 其中的 user是模块前缀名，info是模块里面state属性字段名， 这个数据结构是vue中的ref响应式的
 *  userInfo_.value  // 获取值 ，注意在vue3.0中的template中，直接放入userInfo即（{{userInfo}}），不需要加上userInfo.value 即({{userInfo.value}}),
 *                  // vue 3.x 响应式自动会捕捉的
 */
const get = function (path = '') {
  const { store } = vuexHelper
  if (!path) {
    throw new Error('传入的路径path 不能为空')
  }
  return computed({
    get: () => {
      return path.split('/').reduce((pre, cur) => {
        return pre[cur]
      }, store.state)
    },
    set: () => {
      console.error('当前的vuex中的state处于readonly，如果想修改其值，请使用sync')
    }
  })
}

/**
 * 动态获取vuex中的actions方法
 * @param path
 * @returns {*}
 * @example
 *  import {call} from '~vuex-helper'   // 引入
 *  const logOut_ = call('user/logOut')  // 其中的 user是模块前缀名，logOut是模块里action里面的方法名， 这个数据结构是vue中的ref响应式的
 *  logOut_(args)  // 指定action里面的logOut方法
 */
const call = function (path = '') {
  if (!path) {
    throw new Error('传入的路径path 不能为空')
  }
  const { store } = vuexHelper
  const action = store._actions[path]?.slice?.()?.shift()
  if (!action) {
    console.error(`action对应的${path}不存在`)
  }
  return action
}

/**
 * 将vuex模块中state，每一个属性默认加上mutation方法，
 * @type {{mutations(*=): *}}
 * @example
 *   import {make} from '~vuex-helper'   // 引入
 *   const state = {
 *     info: {},
 *     loading: false
 *   }
 *
 *   const mutations = {
 *     ...make.mutations(state)
 *   }
 *
 *   // 那么mutations值其实变成了
 *   const mutations = {
 *     info(state, payload) {
 *       state.info = payload
 *     }
 *     loading(state, payload) {
 *       state.loading = payload
 *     }
 *   }
 *
 */
const make = {
  mutations(state) {
    return Object.keys(state).reduce((pre, cur) => {
      return {
        ...pre,
        [cur]: function (state, data) {
          state[`${cur}`] = data
        }
      }
    }, {})
  }
}

export default vuexHelper
export { make, sync, get, call }
